<?php
/**
 * Copyright 2011  SURFfoundation
 * 
 * This file is part of ESCAPE.
 * 
 * ESCAPE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * ESCAPE is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with ESCAPE.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * For more information:
 * http://escapesurf.wordpress.com/
 * http://www.surffoundation.nl/
 * 
 * Contact: d.vierkant@utwente.nl
 * 
 * @license http://www.gnu.org/licenses/gpl.html GNU GPLv3
 */
?>
<?php
/**
 * Reset password
 */
class escape_repositoryui_action_ResetPassword extends escape_repositoryui_Action
{
	public function handleRequest()
	{
		$viewName = 'PasswordResetSelect';

		/* @var $repository escape_repository_Repository */
		$repository =& $this->requestAttributes['repository'];
		/* @var $repositoryUi escape_repositoryui_RepositoryUi */
		$repositoryUi =& $this->requestAttributes['repositoryUi'];
		
		// check if password reset is available
		if(!$repository->config['password_reset_enabled'])
		{
			print 'Password reset is not available.';
			return null;
		}
		
		$errorMessages = array();
		
		$this->requestAttributes['hasValidToken'] = false;
		
		// check for a password reset token
		$encryptedToken = $_REQUEST['token'];
		if(!isset($encryptedToken))
		{
			$errorMessages[] = 'Invalid request, no token found.';
		}
		else
		{
			// decrypt the token
			$token = escape_decryptData(base64_decode($encryptedToken), $repository->config['password_reset_encryption_password']);
			
			// validate the token
			if(!preg_match('/^([^:]+)::([^:]+)::([^:]+)$/', $token, $tokenParts))
			{
				$errorMessages[] = 'Invalid password reset token. Please request another password reset email.';
			}
			else
			{
				// get the token parts
				$userId = $tokenParts[1];
				$time = @intval($tokenParts[2]);
				$passwordHashSlice = $tokenParts[3];
				
				$this->requestAttributes['userId'] = $userId;
				
				// check the token expiration
				if($time + $repository->config['password_reset_timeout'] < time())
				{
					$errorMessages[] = 'The password reset token has expired. Please request another password reset email.';
				}
				else
				{
					$user = null;
					try
					{
						// fetch the user object
						$userUri = $repository->convertUserObjectIdToObjectUri($userId);
						$user = $repository->getUserByUri($userUri);
						
						// compare the password hash slice
						if($passwordHashSlice !== substr($user->getPasswordHash(), -8))
						{
							$errorMessages[] = 'The password reset token has expired. Please request another password reset email.';
						}
						else
						{
							// the token is valid
							$this->requestAttributes['hasValidToken'] = true;
							
							// check if a new password was submitted
							$password = $_POST['password'];
							
							if(isset($password))
							{
								// validate the password
								//TODO: keep in sync with AdminCreateUser.php, Signup.php, AdminEditUser.php and Account.php or move to shared function
								if(strlen($password) > 0)
								{
									if(strlen($password) > 32)
									{
										$errorMessages[] = 'Password is too long, please use at most 32 characters';
									}
									if(strlen($password) < 4)
									{
										$errorMessages[] = 'Password is too short, please use at least 4 characters';
									}
								}
								
								if(count($errorMessages) === 0)
								{
									// set the new password
									$user->setPassword($password);
									
									$viewName = 'PasswordResetCompleted';
								}
							}
						}
					}
					catch(Exception $exception)
					{
						$errorMessages[] = 'User "' . htmlspecialchars($userId) . '" does not exist.';
					}
				}
			}
		}
		
		$this->requestAttributes['encryptedToken'] = $encryptedToken;
		$this->requestAttributes['errorMessages'] =& $errorMessages;
		
		return $viewName;
	}
}